package top.sdwu_top.kbase.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import top.sdwu_top.kbase.common.aspect.exception.MyException;
import top.sdwu_top.kbase.common.constants.Constants;
import top.sdwu_top.kbase.common.enums.RoleEnum;
import top.sdwu_top.kbase.dto.ChangePasswordDto;
import top.sdwu_top.kbase.dto.KbaseAuthUserDto;
import top.sdwu_top.kbase.entity.KbaseAuthRole;
import top.sdwu_top.kbase.entity.KbaseAuthUser;
import top.sdwu_top.kbase.entity.KbaseRolePermission;
import top.sdwu_top.kbase.mapper.KbaseAuthUserMapper;
import top.sdwu_top.kbase.service.IKbaseAuthOrgService;
import top.sdwu_top.kbase.service.IKbaseAuthRoleService;
import top.sdwu_top.kbase.service.IKbaseAuthUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.sdwu_top.kbase.service.IKbaseRolePermissionService;
import top.sdwu_top.kbase.vo.KbaseAuthUserVo;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author zhipeng.duan@nvr-china.com
 * @since 2020-02-20
 */
@Service
public class KbaseAuthUserServiceImpl extends ServiceImpl<KbaseAuthUserMapper, KbaseAuthUser> implements IKbaseAuthUserService {

    @Value("admin.username:admin")
    private String adminUsername;

    @Value("${admin.password:123456}")
    private String adminPasswrod;

    @Autowired
    IKbaseAuthRoleService roleService;

    @Autowired
    KbaseAuthUserMapper userMapper;

    @Autowired
    IKbaseRolePermissionService permissionService;

    @Autowired
    IKbaseAuthOrgService orgService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public boolean save(KbaseAuthUser currentUser, KbaseAuthUser user) {
        if (StringUtils.isAnyBlank(user.getOrgId(), user.getPassword(), user.getSsn(), user.getUsername(), user.getPhoneNum(), user.getRoleId())) {
            throw new MyException(50003, "字段校验失败");
        }
        if (!orgService.userCanOperate(currentUser, user.getOrgId())) {
            throw new MyException(50003, "没有权限添加");
        }
        user.setState(Constants.NORMAL);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return super.save(user);
    }

    @Override
    public KbaseAuthUser getBySsn(String ssn) {
        QueryWrapper<KbaseAuthUser> qw = Wrappers.query();
        qw.eq("SSN", ssn);
        KbaseAuthUser user = super.getOne(qw);
        return Objects.nonNull(user) ? user : new KbaseAuthUser();
    }

    @Override
    public KbaseAuthUserDto getCurrentUser(KbaseAuthUser user) {
        if (Objects.isNull(user)) {
            throw new MyException(403, "未登录");
        }
        KbaseAuthUserDto currentUser = userMapper.getUserDtoById(user.getId());
        if (Objects.isNull(currentUser)) {
            throw new MyException(50003, "无此用户");
        }
        return currentUser;
    }

    @Override
    public KbaseAuthUser getManagerByOrgId(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return new KbaseAuthUser();
        }
        QueryWrapper<KbaseAuthUser> qw = Wrappers.query();
        qw.eq("ORG_ID", orgId)
                .or(i->{
                    i.eq("ROLE_ID", RoleEnum.ORG_MANAGER.getKey())
                            .eq("ROLE_ID", RoleEnum.SUPER_ADMIN.getKey());
                });

        qw.last("limit 1");
        KbaseAuthUser user = super.getOne(qw);
        return Objects.nonNull(user) ? user : new KbaseAuthUser();
    }

    @Override
    public UserDetails loadUserByUsername(String username) {
        if (Objects.equals(username, this.adminUsername)) {
            return this.getAdmin();
        }
        QueryWrapper<KbaseAuthUser> qw = Wrappers.query();
        qw.eq("USERNAME", username);
        KbaseAuthUser user = super.getOne(qw);
        if (Objects.isNull(user)) {
            new KbaseAuthUser();
        }
        System.out.println(user.getRoleId());
        user.setRoleList(Lists.newArrayList(roleService.getById(user.getRoleId())));
        return user;
    }

    private UserDetails getAdmin() {
        KbaseAuthUser user = new KbaseAuthUser();
        user.setUsername(this.adminUsername);
        user.setPassword(this.adminPasswrod);
        user.setRoleList(Lists.newArrayList(new KbaseAuthRole()));
        return user;
    }

    public Page<KbaseAuthUserDto> page(KbaseAuthUser user, KbaseAuthUserVo userVo) {
        List<String> userSubOrgList = orgService.getSubOrgIdList(user);
        if (CollectionUtils.isEmpty(userSubOrgList)) {
            throw new MyException(50003, "无权访问");
        }
        QueryWrapper<KbaseAuthUser> qw = Wrappers.query();
        qw.like(StringUtils.isNotBlank(userVo.getOrgName()), "org.ORG_NAME", userVo.getOrgName())
                .like(StringUtils.isNotBlank(userVo.getPhoneNum()), "user.PHONE_NUM", userVo.getPhoneNum())
                .like(StringUtils.isNotBlank(userVo.getSsn()), "user.SSN", userVo.getSsn())
                .eq(StringUtils.isNotBlank(userVo.getRoleId()), "user.ROLE_ID", userVo.getRoleId())
                .in("user.ORG_ID", userSubOrgList)
                .ne("user.id", user.getId());

        return userMapper.mySelectPage(userVo.getPage(), qw);

    }

    @Override
    public boolean delete(KbaseAuthUser user, String id) {
        KbaseAuthUser deleteUser = super.getById(id);
        if (Objects.isNull(deleteUser)) {
            return true;
        }
        if (!orgService.userCanOperate(user, deleteUser.getOrgId())) {
            throw new MyException(50003, "无权操作");
        }
        return super.removeById(id);
    }

    @Override
    public boolean update(KbaseAuthUser currentUser, KbaseAuthUser user) {
        user.setPassword(null);
        if (StringUtils.isBlank(user.getId())) {
            throw new MyException(50003, "字段校验失败,更新用户id不能为空");
        }
        if (!orgService.userCanOperate(currentUser, user.getOrgId())) {
            throw new MyException(50003, "没有修改添加");
        }
        return super.updateById(user);
    }

    @Override
    public KbaseAuthUserDto getUserById(KbaseAuthUser user, String id) {
        KbaseAuthUser tempUser = super.getById(id);
        if (Objects.isNull(tempUser)) {
            return new KbaseAuthUserDto();
        }
        if (!orgService.userCanOperate(user, tempUser.getOrgId())) {
            throw new MyException(403, "无权操作");
        }
        return userMapper.getUserDtoById(id);
    }

    @Override
    public boolean changePassword(KbaseAuthUser user, ChangePasswordDto passwordDto) {
        if (StringUtils.isAnyBlank(passwordDto.getNewPassword(), passwordDto.getOldPassword())) {
            throw new MyException(50003, "校验失败，新旧密码均不能为空");
        }
        KbaseAuthUser currentUser = super.getById(user);
        if (Objects.isNull(currentUser)) {
            throw new MyException(50003, "无当前用户");
        }
        if (!Objects.equals(passwordEncoder.encode(passwordDto.getOldPassword()), currentUser.getPassword())) {
            throw new MyException(50003, "旧密码校验失败");
        }
        UpdateWrapper<KbaseAuthUser> uw = Wrappers.update();
        uw.eq("id", user.getId());
        uw.set("password", passwordEncoder.encode(passwordDto.getNewPassword()));
        return super.update(uw);
    }

    @Override
    public boolean updateNowUser(KbaseAuthUser currentUser, KbaseAuthUser user) {
        user.setPassword(null);
        user.setId(currentUser.getId());
        return super.updateById(user);
    }


}
